using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using Csla.Validation;

namespace fitnesstrack.library
{ 
	[Serializable()] 
	public class TrainingDetail : Csla.BusinessBase<TrainingDetail>
	{
		#region Business Properties and Methods

		//declare members
		private int _id = 0;
		private int _trainingSessionID = 0;
		private int _exerciseID = 0;
		private short _setNumber = 0;
		private decimal _weight = 0;
		private short _reps = 0;

		[System.ComponentModel.DataObjectField(true, true)]
		public int Id
		{
			get
			{
				CanReadProperty("Id", true);
				return _id;
			}
		}

		public int TrainingSessionID
		{
			get
			{
				CanReadProperty("TrainingSessionID", true);
				return _trainingSessionID;
			}
			set
			{
				CanWriteProperty("TrainingSessionID", true);
				if (!_trainingSessionID.Equals(value))
				{
					_trainingSessionID = value;
					PropertyHasChanged("TrainingSessionID");
				}
			}
		}

		public int ExerciseID
		{
			get
			{
				CanReadProperty("ExerciseID", true);
				return _exerciseID;
			}
			set
			{
				CanWriteProperty("ExerciseID", true);
				if (!_exerciseID.Equals(value))
				{
					_exerciseID = value;
					PropertyHasChanged("ExerciseID");
				}
			}
		}

		public short SetNumber
		{
			get
			{
				CanReadProperty("SetNumber", true);
				return _setNumber;
			}
			set
			{
				CanWriteProperty("SetNumber", true);
				if (!_setNumber.Equals(value))
				{
					_setNumber = value;
					PropertyHasChanged("SetNumber");
				}
			}
		}

		public decimal Weight
		{
			get
			{
				CanReadProperty("Weight", true);
				return _weight;
			}
			set
			{
				CanWriteProperty("Weight", true);
				if (!_weight.Equals(value))
				{
					_weight = value;
					PropertyHasChanged("Weight");
				}
			}
		}

		public short Reps
		{
			get
			{
				CanReadProperty("Reps", true);
				return _reps;
			}
			set
			{
				CanWriteProperty("Reps", true);
				if (!_reps.Equals(value))
				{
					_reps = value;
					PropertyHasChanged("Reps");
				}
			}
		}
 
		protected override object GetIdValue()
		{
			return _id;
		}

		#endregion //Business Properties and Methods

		#region Validation Rules
		private void AddCustomRules()
		{
			//add custom/non-generated rules here...
		}

		private void AddCommonRules()
		{

		}

		protected override void AddBusinessRules()
		{
			AddCommonRules();
			AddCustomRules();
		}
		#endregion //Validation Rules

		#region Authorization Rules
		protected override void AddAuthorizationRules()
		{
			//TODO: Define authorization rules in TrainingDetail
			//AuthorizationRules.AllowRead("Id", "TrainingDetailReadGroup");
			//AuthorizationRules.AllowRead("TrainingSessionID", "TrainingDetailReadGroup");
			//AuthorizationRules.AllowRead("ExerciseID", "TrainingDetailReadGroup");
			//AuthorizationRules.AllowRead("SetNumber", "TrainingDetailReadGroup");
			//AuthorizationRules.AllowRead("Weight", "TrainingDetailReadGroup");
			//AuthorizationRules.AllowRead("Reps", "TrainingDetailReadGroup");

			//AuthorizationRules.AllowWrite("TrainingSessionID", "TrainingDetailWriteGroup");
			//AuthorizationRules.AllowWrite("ExerciseID", "TrainingDetailWriteGroup");
			//AuthorizationRules.AllowWrite("SetNumber", "TrainingDetailWriteGroup");
			//AuthorizationRules.AllowWrite("Weight", "TrainingDetailWriteGroup");
			//AuthorizationRules.AllowWrite("Reps", "TrainingDetailWriteGroup");
		}


		public static bool CanGetObject()
		{
			//TODO: Define CanGetObject permission in TrainingDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("TrainingDetailViewGroup"))
			//	return true;
			//return false;
		}

		public static bool CanAddObject()
		{
			//TODO: Define CanAddObject permission in TrainingDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("TrainingDetailAddGroup"))
			//	return true;
			//return false;
		}

		public static bool CanEditObject()
		{
			//TODO: Define CanEditObject permission in TrainingDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("TrainingDetailEditGroup"))
			//	return true;
			//return false;
		}

		public static bool CanDeleteObject()
		{
			//TODO: Define CanDeleteObject permission in TrainingDetail
			return true;
			//if (Csla.ApplicationContext.User.IsInRole("TrainingDetailDeleteGroup"))
			//	return true;
			//return false;
		}
		#endregion //Authorization Rules

		#region Factory Methods
		private TrainingDetail()
		{ /* require use of factory method */ }

		public static TrainingDetail NewTrainingDetail()
		{
			if (!CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a TrainingDetail");
			return DataPortal.Create<TrainingDetail>();
		}

		public static TrainingDetail GetTrainingDetail(int id)
		{
			if (!CanGetObject())
				throw new System.Security.SecurityException("User not authorized to view a TrainingDetail");
			return DataPortal.Fetch<TrainingDetail>(new Criteria(id));
		}

		public static void DeleteTrainingDetail(int id)
		{
			if (!CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a TrainingDetail");
			DataPortal.Delete(new Criteria(id));
		}

		public override TrainingDetail Save()
		{
			if (IsDeleted && !CanDeleteObject())
				throw new System.Security.SecurityException("User not authorized to remove a TrainingDetail");
			else if (IsNew && !CanAddObject())
				throw new System.Security.SecurityException("User not authorized to add a TrainingDetail");
			else if (!CanEditObject())
				throw new System.Security.SecurityException("User not authorized to update a TrainingDetail");

			return base.Save();
		}

		#endregion //Factory Methods

		#region Data Access

		#region Criteria

		[Serializable()]
		private class Criteria
		{
			public int Id;

			public Criteria(int id)
			{
				this.Id = id;
			}
		}

		#endregion //Criteria

		#region Data Access - Create
		[RunLocal]
		protected override void DataPortal_Create()
		{
			ValidationRules.CheckRules();
		}

		#endregion //Data Access - Create

		#region Data Access - Fetch
		private void DataPortal_Fetch(Criteria criteria)
		{
			using (SqlConnection cn = new SqlConnection(Database.fitnesstrackConnection))
			{
				cn.Open();

				ExecuteFetch(cn, criteria);
			}//using
		}

		private void ExecuteFetch(SqlConnection cn, Criteria criteria)
		{
			using (SqlCommand cm = cn.CreateCommand())
			{
				cm.CommandType = CommandType.StoredProcedure;
				cm.CommandText = "GetTrainingDetail";

				cm.Parameters.AddWithValue("@ID", criteria.Id);

				using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
				{
					FetchObject(dr);
					ValidationRules.CheckRules();

					//load child object(s)
					FetchChildren(dr);
				}
			}//using
		}

		private void FetchObject(SafeDataReader dr)
		{
			dr.Read();
			_id = dr.GetInt32("ID");
			_trainingSessionID = dr.GetInt32("TrainingSessionID");
			_exerciseID = dr.GetInt32("ExerciseID");
			_setNumber = dr.GetInt16("SetNumber");
			_weight = dr.GetDecimal("Weight");
			_reps = dr.GetInt16("Reps");
		}

		private void FetchChildren(SafeDataReader dr)
		{
		}
		#endregion //Data Access - Fetch

		#region Data Access - Insert
		protected override void DataPortal_Insert()
		{
			using (SqlConnection cn = new SqlConnection(Database.fitnesstrackConnection))
			{
				cn.Open();

				ExecuteInsert(cn);

				//update child object(s)
				UpdateChildren(cn);
			}//using

		}

		private void ExecuteInsert(SqlConnection cn)
		{
			using (SqlCommand cm = cn.CreateCommand())
			{
				cm.CommandType = CommandType.StoredProcedure;
				cm.CommandText = "AddTrainingDetail";

				AddInsertParameters(cm);

				cm.ExecuteNonQuery();

				_id = (int)cm.Parameters["@NewID"].Value;
			}//using
		}

		private void AddInsertParameters(SqlCommand cm)
		{
			if (_trainingSessionID != 0)
				cm.Parameters.AddWithValue("@TrainingSessionID", _trainingSessionID);
			else
				cm.Parameters.AddWithValue("@TrainingSessionID", DBNull.Value);
			if (_exerciseID != 0)
				cm.Parameters.AddWithValue("@ExerciseID", _exerciseID);
			else
				cm.Parameters.AddWithValue("@ExerciseID", DBNull.Value);
			if (_setNumber != 0)
				cm.Parameters.AddWithValue("@SetNumber", _setNumber);
			else
				cm.Parameters.AddWithValue("@SetNumber", DBNull.Value);
			if (_weight != 0)
				cm.Parameters.AddWithValue("@Weight", _weight);
			else
				cm.Parameters.AddWithValue("@Weight", DBNull.Value);
			if (_reps != 0)
				cm.Parameters.AddWithValue("@Reps", _reps);
			else
				cm.Parameters.AddWithValue("@Reps", DBNull.Value);
			cm.Parameters.AddWithValue("@NewID", _id);
			cm.Parameters["@NewID"].Direction = ParameterDirection.Output;
		}
		#endregion //Data Access - Insert

		#region Data Access - Update
		protected override void DataPortal_Update()
		{
			using (SqlConnection cn = new SqlConnection(Database.fitnesstrackConnection))
			{
				cn.Open();

				if (base.IsDirty)
				{
					ExecuteUpdate(cn);
				}

				//update child object(s)
				UpdateChildren(cn);
			}//using

		}

		private void ExecuteUpdate(SqlConnection cn)
		{
			using (SqlCommand cm = cn.CreateCommand())
			{
				cm.CommandType = CommandType.StoredProcedure;
				cm.CommandText = "UpdateTrainingDetail";

				AddUpdateParameters(cm);

				cm.ExecuteNonQuery();

			}//using
		}

		private void AddUpdateParameters(SqlCommand cm)
		{
			cm.Parameters.AddWithValue("@ID", _id);
			if (_trainingSessionID != 0)
				cm.Parameters.AddWithValue("@TrainingSessionID", _trainingSessionID);
			else
				cm.Parameters.AddWithValue("@TrainingSessionID", DBNull.Value);
			if (_exerciseID != 0)
				cm.Parameters.AddWithValue("@ExerciseID", _exerciseID);
			else
				cm.Parameters.AddWithValue("@ExerciseID", DBNull.Value);
			if (_setNumber != 0)
				cm.Parameters.AddWithValue("@SetNumber", _setNumber);
			else
				cm.Parameters.AddWithValue("@SetNumber", DBNull.Value);
			if (_weight != 0)
				cm.Parameters.AddWithValue("@Weight", _weight);
			else
				cm.Parameters.AddWithValue("@Weight", DBNull.Value);
			if (_reps != 0)
				cm.Parameters.AddWithValue("@Reps", _reps);
			else
				cm.Parameters.AddWithValue("@Reps", DBNull.Value);
		}

		private void UpdateChildren(SqlConnection cn)
		{
		}
		#endregion //Data Access - Update

		#region Data Access - Delete
		protected override void DataPortal_DeleteSelf()
		{
			DataPortal_Delete(new Criteria(_id));
		}

		private void DataPortal_Delete(Criteria criteria)
		{
			using (SqlConnection cn = new SqlConnection(Database.fitnesstrackConnection))
			{
				cn.Open();

				ExecuteDelete(cn, criteria);

			}//using

		}

		private void ExecuteDelete(SqlConnection cn, Criteria criteria)
		{
			using (SqlCommand cm = cn.CreateCommand())
			{
				cm.CommandType = CommandType.StoredProcedure;
				cm.CommandText = "DeleteTrainingDetail";

				cm.Parameters.AddWithValue("@ID", criteria.Id);

				cm.ExecuteNonQuery();
			}//using
		}
		#endregion //Data Access - Delete
		#endregion //Data Access
	}
}
